package com.luobr.backend.handler;

import cn.hutool.core.util.StrUtil;
import com.luobr.backend.annotation.AuthCheck;
import com.luobr.backend.common.ResponseCode;
import com.luobr.backend.constant.UserConstant;
import com.luobr.backend.exception.BusinessException;
import com.luobr.backend.exception.ThrowUtils;
import com.luobr.backend.model.entity.User;
import com.luobr.backend.model.enums.UserRoleEnum;
import com.luobr.backend.model.vo.user.UserLoginVO;
import com.luobr.backend.service.UserService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @author: 罗念笙
 * @date: 2025/2/20 22:00
 * 利用 AOP 切面对用户权限进行控制
 */
@Aspect
@Component
public class AuthInterceptorHandler {
    @Resource
    private UserService userService;

    @Around("@annotation(authCheck)")
    public Object doInterceptor(ProceedingJoinPoint joinPoint,AuthCheck authCheck) throws Throwable {
        // 获取注解上配置的角色值
        String roleValue = authCheck.roleValue();
        // 获取当前用户的角色(权限)
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        // 校验是否登录
        UserLoginVO loginUser = userService.getLoginUser(request);
        ThrowUtils.throwIf(loginUser == null,new BusinessException(ResponseCode.NOT_LOGIN_ERROR));
        // 校验注解是否有配置角色值,没有则直接放行
        if(StrUtil.isBlank(roleValue)) {
            return joinPoint.proceed();
        }
        // 如果注解配置了管理角色,则需要判断请求用户是否是管理员
        String adminValue = UserRoleEnum.ADMIN.getValue();
        ThrowUtils.throwIf(adminValue.equals(roleValue) && !adminValue.equals(loginUser.getUserRole()),
                new BusinessException(ResponseCode.NO_AUTH_ERROR));
        return joinPoint.proceed();
    }

}
